در سورس کدی که استاد برای تدریس و پیاده سازی ابتدایی سیستم عامل ارائه کرد . مشکلات و مطالبی وجود داشت . خصوصا در محاسبه LBA و CHS در زیر تعریف اصلی و اینکه این دو عبارت به چه معنا هستند اومده و فرمول محاسبه اونها هم قرار داده شده . بشدت پیشنهاد میکنم بعد از خوندن این تعریف ها به لینکی که در انتها دادم ( آدرس وبلاگ ) مراجعه کنید و مابقی مطالب رو حتما بخونید تا متوجه قضایا بشید . ( مطالب وبلاگ بعد از ویرایش اینجا قرار داده میشه تا اون زمان لینک به مطالب داده میشه )
زمانی که ما اولین کلاستر منطقی رو از بایت 26 تا 27 root entry (از تو روت دایرکتوری) بازیابی میکنیم . مستقیما و بلافاصله نمینونیم ازش استفاده کنیم . چرا ؟ برای اینکه این کلاستر یه ادرس خطی رو بما ارائه میده . در حالی که برای لود کردن سکتورها ما به ادرس سگمنت/ترک/هد نیاز داریم (برای وقفه شماره 13) . دو راه برای دسترسی به دیسک وجود داره . یا از طریق ادرس دهی CHS که میشه Cylinder/Head/Sector استفاده میکنیم یا از ادرس دهی بلاگ منطقی یا LBA . LBA مکانهای روی دیسک رو بصورت ایندکسی بما ارائه میکنه . یعنی اینکه بلاک اول هست صفر بعد یک و الی آخر . LBA سکتورها رو بصورت شماره های متوالی بما ارئه میکنه .که از LBA0 شروع میشه و ادامه پیدا میکنه . پس برای استفاده از دیسک باید نحوه تبدیل LBA به CHSو بلعکس رو بدیونیم . فرمول زیر آدرس مبتنی بر CHS رو به آدرس مبتنی بر LBA تبدیل میکنه . LBA = (cluster - 2) * sectors dar har cluster
شماره ای که تو روت انتری هست یک عدد نسبی هست! شماره کلاستر! این شماره کلاستر باید مشخص بشه که تو کدوم بلاکه ( LBA برای همین استفاده میشه )و بعد که مشخص شد تو کدوم بلاکه اون بلاک رو مشخصات سکتور فیزیکی وشماره شیار و ایناشو بدست میاریمو دادشو میخونیم. در این جا توضیحاتی در مورد سورس کرنل سیستم عامل اومده و من اینجا چگونگی محاسبه و پیدا کردن مکان تکه های مختلف فایل(وقتی فایل بیشتر از یک سکتور باشه) و بعد لود کردن اون رو توضیح دادم. : ------ ببینید وقتی ما شماره کلاستر آغازین فایلمون رو از تو روت انتری گرفتیم باید مشخص کنیم این شماره تو کدوم بلاک روی دیسکه!! برای همین قدم اول مشخص کردن بلاکی هست که این مقدار ما توشه . پس طی یک فرمول این کارو میکنیم(نکته پایینو بخونید). بعد طی مرحله بعدی که فهمیدیم این تو کدوم بلاک هست حالا میریم برای خوندن و برای خوندن چون به ادرس سکتور فیزیکی شماره شیار فیزیکی و ... نیاز داریم این ادرس بلاک رو میریم و پیدا میکنیم این بلاک الان دقیقا کجای دیسک قرار گرفته . قبلا گفته بودم که LBA میاد دیسک رو بلاک بندی میکنه یعنی فضای دیسک رو بصورت بلاک یک بلاک دو .... در نظر میگیره . حالا که فهمیدیم کلاستر ما تو کدوم بلاکه باید ببینم این بلاک ما تو کدوم سکتور و ایناست . برای همین بلاک رو با فرمول CHS تبدیل میکنیم و داده ها رو میخونیم ( تو تابع رید سکتور). نکته : دادهای ما کجا ذخیره شدن؟ ها ؟ تو بخش داده دیگه درسته ؟ پس برای همین هست که ما اخر تابعclusterlba میایم با datasector مقدار بدست اومده رو جمع میکنیم که یعنی بلاکی که ما دنبالشیم حتما از اینجا به بعد هست ( نا سلامتی میخواییم داده بخونیم داده هم فقط ازاونجا به بعد هست .. و اگر بلاکی هست باید اونجا باشه . ما هم واسه همین میریم اونجا) حالا وقتی میخواییم کلاستر بعدی رو پیدا کنیم خیلی راحت شماره کلاستر بالا رو هنوز داریم ( تو متغییر کلاستر ) میبینیم این کلاستر زوج هست یا فرد بعد با توجه به اون شماره کلاستر بعدی رو بازیابی میکنیم(با همون شیفت دادن ها بدست میاد) و میریم بالا مثل بار اول ,اول میبینم که تو کدوم بلاکه این بعد برای خوندن سکتورش ,مشخصات بلاک رو تبدیل میکنیم به مشخصات سکتور فیزیک وشماره شیار فیزیکی و غیره و دادهاشو میخونیم . راستی این پست پایینی رو حتما بخونید حتما ها .چون در مورد LBA ها من توضیح دادم که چی هست. فرمول درست تبدیل LBA به CHS هست . همونطور که تو پست پایینی گفتم سکتور فیزیک از باقیمونده تقسیم +1 بدست میاد . همین دیگه فرمول اصلی تبدیل LBA به CHS اینه
حالا فرمول اصلی برای تبدیل ال بی ای به سی ایج اس :LBA to CHS mapping
CHS-tuples can be mapped onto LBA (Logical Block Addressing) addresses using the following formula
Where A is the LBA address, Nheads is the number of heads on the disk, Nsectors is the number of sectors per track, and (c,h,s) is the CHS address From CHS to LBA LBA = ( ( CYL * HPC + HEAD ) * SPT ) + SECT - 1
LBA: linear base address of the block CYL: value of the cylinder CHS coordinate HPC: number of heads per cylinder for the disk HEAD: value of the head CHS coordinate
SPT: number of sectors per track for the disk SECT: value of the sector CHS coordinate
سلام من تو کلاس امروز یه سری حرف زدم در مورد بعضی از توابع صحبت هایی که شد باعث شد برم ببینم چک کنم ببینم حرفام درست بوده یا نه ! سرچ کردم دیدم حرفم درست بوده! و این باعث شد یه سری اشکال تو کد برنامه پیدا بشه ! از این قراره :تو تابع LBACHS که کار تبدیل فرم ادرس دهی خطی رو به ادرس دهی فیزیک انجام میده یه قضیه هست . من تو کلاس گفتم هر وقت تقسیم انجام بشه . اگه تقسیم بر دو بایت هست . باقیمانده وارد ثبات DX میشه و باز تو DX این ثبات dl هست که مقدار عددی رو تو خودش داره . و AX هم بعد از تقسیم شامل خارج قسمت میشه . برای مطمعن شد میتونید به کتاب اموزش اسمبلی جعفر نژاد مراجعه کنید یا این سایت رو ببینید با این تفاسیر اگه حرف من درست باشه کسی که این فرمولا رو نوشته بالا اشتباه این کارو کرده چرا ؟ چون که برای محاسبه سکتور فیزیکی . ما سکتور منطقی رو تقسیم بر تعداد سکتور در هر شیار میکنیم و "باقیمونده تقسیم " یکی بهش اضافه میشه و این میشه سکتور ما !!!" باقیمانده تقسیم تو dl قرار گرفته! برای اینکه مطمئن بشید درست میگم . یه نگاهی به فرمول محاسبه هد بکنید . تو فرمول محاسبه هد اومده که باقیمانده تقسیم "سکتور منطقی " بر تعداد سکتور در هر ترک میشه هد ما ! و ببینید این مقدار بعد از تقسیم از کجا اومده! از dl ! یعنی بعد از تقسیم dl حاوی باقیمانده هست ! و برای محاسبه ترک فیزیکی ما به خارج قسمت تقسیم "سکتور منطقی بر تعداد سکتور در هر ترک " نیاز داریم . که همونطور که میبینید از AL استفاده شده! یعنی AX میشه خارج قسمت که باز تو این ثابت این Al هست که مقدار خارج قسمت توش ذخیره میشه .! پس همه اینها به چه معناست! حرفی که تو کلاس زدم درست بوده! و یه شیر پاک خورده ای این فرمول رو اشتباه نوشته برای سکتور
absolute track = logical sector / (sectors per track * number of heads); ; absolute head = (logical sector / sectors per track) MOD number of heads; ; absolute sector = (logical sector / sectors per track) + 1; ;=======================================; LBACHS: xor dx, dx ; prepare dx:ax for operation Lea SI, bpbSectorsPerTrack div WORD PTR[SI] ; calculate inc dl ; adjust for sector 0 Lea SI, absoluteSector mov BYTE PTR[SI], dl xor dx, dx ; prepare dx:ax for operation Lea SI, bpbHeadsPerCylinder div WORD PTR[SI] ; calculate Lea SI, absoluteHead mov BYTE PTR[SI], dl Lea SI, absoluteTrack mov BYTE PTR[SI], al ret
دو اینکه من رفتم دنبال LBA وCHS چیز جالبی پیدا کردم بخونید !:
توضیحات در مورد LBA و CHS که در بالا گفته شد
بسم الله الرحمن الرحیم توضیحاتی در مورد LBA و CHS زمانی که ما اولین کلاستر منطقی رو از بایت 26 تا 27 root entry (از تو روت دایرکتوری) بازیابی میکنیم . مستقیما و بلافاصله نمینونیم ازش استفاده کنیم . چرا ؟ برای اینکه این کلاستر یه ادرس خطی رو بما ارائه میده . در حالی که برای لود کردن سکتورها ما به ادرس سگمنت/ترک/هد نیاز داریم (برای وقفه شماره 13) . دو راه برای دسترسی به دیسک وجود داره . یا از طریق ادرس دهی CHS که میشه Cylinder/Head/Sector استفاده میکنیم یا از ادرس دهی بلاگ منطقی یا LBA . LBA مکانهای روی دیسک رو بصورت ایندکسی بما ارائه میکنه . یعنی اینکه بلاک اول هست صفر بعد یک و الی آخر . LBA سکتورها رو بصورت شماره های متوالی بما ارئه میکنه .که از LBA0 شروع میشه و ادامه پیدا میکنه . پس برای استفاده از دیسک باید نحوه تبدیل LBA به CHSو بلعکس رو بدیونیم . فرمول زیر آدرس مبتنی بر CHS رو به آدرس مبتنی بر LBA تبدیل میکنه . LBA = (cluster - 2) * sectors dar har cluster
توضیحات در مورد LBA و CHS که در بالا گفته شد
شماره ای که تو روت انتری هست یک عدد نسبی هست! شماره کلاستر! این شماره کلاستر باید مشخص بشه که تو کدوم بلاکه ( LBA برای همین استفاده میشه )و بعد که مشخص شد تو کدوم بلاکه اون بلاک رو مشخصات سکتور فیزیکی وشماره شیار و ایناشو بدست میاریمو دادشو میخونیم ( اطلاعات بیشتر پست بالا) و فرمول زیر آدرس مبتنی بر LBA رو به آدرس مبتنی بر CHS تبدیل میکنه .
absolute sector = (logical sector / sectors per track) + 1 absolute head = (logical sector / sectors per track) MOD number of heads absolute track = logical sector / (sectors per track * number of heads
حالا نکته جالبش کجاست ! این فرمول رو این فرد اشتباه نوشته! (فرمول محاسبه سکتور)(دلیل اشتباه بودنشم بالا گفتم ) حالا دلیل من بکنار . بالای سایتش یه چیزی نظر منو بخودش جلب کرد . : و درستش اینه (توضیحات اصلی و کامل در این زمینه تو پست بالاییه )
absolute sector = (LBA % sectors per track) + 1 absolute head = (LBA / sectors per track) MOD number of heads absolute track = (LBA / (sectors per track * number of heads
صحفه قبلش :
Please note: This chapter is planned to be updated soon to fix errors and provide more through information on topics. از اونجایی که این بنده خدا خودش انگلیسی زبان نیست و کلا غلط های زیادی داره و با توجه به اینکه خودشم گفته بعضی جاها نیاز به اپدیت داره و error!! هایی هم وجود داره و بیشتر به منظور یادگیری اصول اومده مطالب رو عنوان کرده! در نتیجه فکر میکنم اون فرمول رو اشتباه نوشته و کاری که برای بدست اوردن سکتور فیزیکی میکنیم اونی نیست که در قالب فرمول گفته!
-------------------------- بک نکته دیگه در مورد استک که تو کلاس یادم رفت بگم . ببینید ما به همون ترتیبی که ثباتها رو تو استک پوش کردیم به همون صورت حالا معکوسش اونا رو پاپ میکنیم . یعنی چی ؟ یعنی اگه من
push ax push bx موقع پاپ کردن باید بنویسم pop bx pop ax
همین ! اینو یادم رفته بود بگم . ================== مهم : در مورد BPB یا Bios Prameter Block و اینکه چرا ما اینو اول تعریف میکنیم و آخر تعریف نمیکنیم این مطلب رو بخونید . (سر نماز یادم اومد ) ببینید بزارید با هم یکبار دیگه ساختار جدول فت رو ببینیم :
و حالا اطلاعات خود بوت سکتور !!! که تو فایل اولی که برای دنلود گذاشته بودم .
توضیح :
سه بایت اول مربوط به پرش هست (پرش ما ). هشت بایت بعدی اسم شرکت سازنده یا اصطلاحا OEM IDهست که جمعا میشه 11 بایت .(منظورش متغییری هست که زیر جامپ تعریف کردیم !) بعد از این 11 بایت ما یه چیزی داریم با نام BPB که مخفف bios parameter Block هست به معنای بلاک پارامتری بایوس(یعنی همه اون متغییر هایی که تعریف کردیم بعدش مثل تعداد سکتور در هر کلاستر و غیره اینا تشکیل BPBرو میدن) . بطور خیلی خلاصه .BPB اطلاعات لازم و مورد نیاز برای بخش اجرایی بوت سکتور(یعنی بوت لودر ما) رو فراهم میکنه تا بتونه فایل NTLDR رو پیدا کنه(فایل NTLDR هم مربوط به ویندوز هست . این فایل خودش وظیفش لود کردن بخش دوم کرنل هست . برای ما این فایل میتونه خود کرنل ما باشه . ) .بخاطر اینکه BPB همیشه از یه آفست شروع میشه(یعنی همیشه باید اون بالا تعریف بشه) پارامتر های استاندار هم همیشه تو یه مکان مشخص وجوددارن(یعنی مثلا جایی که میشه تعداد سکتور در هر کلاستر رو گرفت و فهمید قضیه دیسک چجوریه همیشه یک جاست).تمامی قابلیت های تنظیمی مرتبط با اجرای دیسک ها مختلف با اندازه ها و ساختار های مختلف در این BPB کپسوله هست.(یعنی قرار داره .باز یعنی بکمک این میشه با انواع و اقسام دیسک های مختلف کار کرد چون مشخصاتشون تو این ذخیره میشه).BPB یه فرمت خاص داره که هربخشش معرف یه سری اطلاعات خاصه . این فرمت خاص رو من تو جدول بالا پیاده کردم . پس الان متوجه شدید که چرا 11 بایت اول خالیه!(اینم یه سوال دیگه از تمرین استاد بود)(یعنی متغییری نبود که توش مقدار بدیم!! سه بایت اول جامپ بود که خودمون بالا نوشتیم ! بعدش 8 بایت میموند که بعنوان یه متغییر بعد از جامپ تعریف کردیم و بعدش هم که BPBشروع میشه یعنی همون اطلاعات اساسی برای کار با دیسک )خوب حالا همه اینا یعنی چی ؟ -------------------- یعنی چی ؟ یعنی اینکه بوت لودر ما !!! توی سکتور صفر وجود داره!!! یعنی ما داریم بوت سکتور رو میسازیم!!! برای همین هم هست که اون جدول رو اول برناممون میزاریم . چون توی بوت سکتور اینطوری باید قرار بگیره .! دستورات code segmnet ! و بعدش assume cs:code اینها همش مال موفعی هست که ما داریم برنامه رو مینویسیم ! برای این هست که کامپایلر بما گیر نده! وقتی که بوت لودر ما بخواد تو سکتور صفر قرار بگیره!!! از جامپ ما شروع میشه و میره تا آخر !!(یعنیاولین چیزی که تو بوت سکتور یا سکتور صفر پیدا میکنیم این دستور جامپ ماست ! بعدش سه بایت میرید جلو میرسید به اسم شرکت سازنده باز 8 تا دیگه میرید جلو و میرسید به اطلاعات مربوط به تعداد بایت در هر سکتور و الی اخر) این یعنی اینکه JMP ما 3 بایت اشغال میکنه ( چون far jump هست!) و بعدش دقیقا یه 8 بایت داده برای OEMname هست! و این ساختار ادامه پیدا میکنه تا آخر . !!!!این یعنی ما داریم ساختار بوت سکتور رو درست میکنیم . باز یعنی داریم تو بوت سکترو دادهای حیاتی رو قرار میدیم که هر بار که سیستم میخواد بوت بشه بایوس به این سکتور صفر مراجعه میکنه و با دیدین این ترتیب اطلاعات شروع به کار میکنه ! برای همین اگه ما این داده ها رو که بجای اینکه ابتدای سکتور صفر قرار بدیم ببریم انتهای سکتور صفر . با ارور DISK NOT FORMATTED مواجه میشم . الان تونستم برسونم که چرا ما باید اول بنویسیم اون اطلاعات رو ؟ آقا ما باید سکتور صفر و بر اساس طرح بالایی که وجودداره پیاده کنیم تا اصولی کار کرده باشیم ومشکلی پیش نیاد .وگرنه وقتی رفتیم تو سیستم عاملمون میگه دیسک فرمت شده نیست!!! چرا چون اطلاعاتی که باید تو بایتهای اول سکتور صفر پیدا کنه پیدا نمیکنه و فکر میکنه دیسک فرمت نشده که اینا این تو نیستن!!! حالا متوجه شدید ؟ برای همینه که بالا تو توضیحات کد رو قرمز کردم چون BPB همیشه باید یه جای ثابت باشه! و دسترسی به اون ها هم چون جاشون ثابته بصورت ثابت انجام میگیره. امیدوارم رسونده باشم منظورمو اگه نه فرداایشالله با هم صحبت میکنیم .
این دیگه کامل گفته یعنی چی :
The Reserved sectors, located at the very beginning. The first reserved sector (sector 0) is the Boot Sector (aka Partition Boot Record). It includes an area called the BIOS Parameter Block (with some basic file system information, in particular its type, and pointers to the location of the other sections) and usually contains the operating system's boot loader code. The total count of reserved sectors is indicated by a field inside the Boot Sector. Important information from the Boot Sector is accessible through an operating system structure called the Drive Parameter Block in DOS and OS/2. For FAT32 file systems, the reserved sectors include a File System Information Sector at sector 1 and a Backup Boot Sector at Sector 6
علاقه مندی ها (Bookmarks)